package com.game.logic.ranking;

import com.coment.cfg.luban.constant.AIDCFG;
import com.coment.enums.RankingType;
import com.coment.po.UserInfo;
import com.coment.po.UserPlayInfo;
import com.coment.po.roles.Roles;
import com.game.dao.user.UserDao;
import com.game.dao.user.UserPlayInfoDao;
import com.game.dao.user.roles.RolesDao;
import com.game.logic.core.ranking.RakingService;
import com.game.logic.roles.RolesCultivateLogic;
import jakarta.annotation.Resource;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
public class WordRakingService {
    @Resource
    private RolesDao rolesDao;

    @Resource
    private UserDao userDao;

    private final RakingService<Integer> rakingService;
    @Autowired
    private UserPlayInfoDao userPlayInfoDao;

    public WordRakingService(
            RolesDao rolesDao,
            UserDao userDao,
            RedisTemplate<String, Integer> genericRedisTemplate
    ) {
        this.rolesDao = rolesDao;
        this.userDao = userDao;

        this.rakingService = new RakingService<>(genericRedisTemplate);
    }

    public void obtainWorldRankingReward(@NotNull Integer userInfoId) {

    }

    @Data
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    @EqualsAndHashCode(of = {"userInfoId"})
    public static class WorldFightingCapacityRakingInfo {
        ///  玩家id
        private Integer userInfoId;

        /// 头像
        private String avatar;

        /// 玩家名字
        private String name;

        /// 玩家称号
        private Integer title;

        /// 玩家角色id
        private String rolesId;

        /// 卡牌id
        private Integer cardId;

        /// 角色等级
        private Integer lv;

        /// 战力
        private Double fightingCapacity;
    }


    private static final ConcurrentHashMap<Object, WorldFightingCapacityRakingInfo> worldFightingCapacityRakingInfoMap = new ConcurrentHashMap<>();

    /// 世界榜单刷新
    @Async
    @Scheduled(fixedRate = 600_000, initialDelay = 10_000)
    public void worldFightingCapacityRaking() {
        try {
            log.info("世界榜单刷新");

            // 清榜
            rakingService.removeAll("", RankingType.worldFightingCapacityRaking);

            List<UserInfo> userInfoList = userDao.findAll();
            for (UserInfo userInfo : userInfoList) {
                Integer userInfoId = userInfo.getId();
                UserPlayInfo userPlayInfo = userPlayInfoDao.findByUserInfoIdOrCreate(userInfoId);

                WorldFightingCapacityRakingInfo rakingInfo = new WorldFightingCapacityRakingInfo();
                rakingInfo.setUserInfoId(userInfoId);
                rakingInfo.setAvatar(userInfo.getAvatar());
                rakingInfo.setName(userInfo.getName());
                rakingInfo.setTitle(userPlayInfo.getRecentlyPlayedTitleId());
                rakingInfo.setFightingCapacity(0D);

                List<Roles> rolesList = rolesDao.searchAllByUserInfoId(userInfoId);

                Double maxFightingCapacity = 0D;
                Roles maxRoles = null;

                for (Roles roles : rolesList) {
                    Double capacity = RolesCultivateLogic.tryCountFightingCapacity(roles);
                    if (capacity > maxFightingCapacity) {
                        maxRoles = roles;
                        maxFightingCapacity = capacity;
                    }
                }

                if (maxRoles != null) {
                    rakingInfo.setFightingCapacity(maxFightingCapacity);
                    rakingInfo.setRolesId(maxRoles.id);
                    rakingInfo.setLv(maxRoles.rolePanel.cultivatePanel.base.get(AIDCFG.level).intValue());
                    rakingInfo.setCardId(maxRoles.cardId);

                }
                worldFightingCapacityRakingInfoMap.put(userInfoId, rakingInfo);

                rakingService.addLine(
                        "",
                        RankingType.worldFightingCapacityRaking,
                        userInfoId,
                        maxFightingCapacity
                );
            }
        } catch (Exception e) {
            log.error("世界榜单刷新失败", e);
        }
    }

    /// 获取世界榜单
    public List<RakingService.RankInfo<WorldFightingCapacityRakingInfo>> list(int s, int t) {
        List<RakingService.RankInfo<Integer>> rankRangeInfo = rakingService.getRankRangeInfo("", RankingType.worldFightingCapacityRaking, s, t);
        return rankRangeInfo.stream().map(rankInfo -> {
            Integer id = rankInfo.id();
            WorldFightingCapacityRakingInfo rakingInfo = worldFightingCapacityRakingInfoMap.get(id);
            return new RakingService.RankInfo<>(rakingInfo, rankInfo.rank(), rankInfo.score());
        }).toList();
    }

    /// 获取玩家世界榜单
    public Long get(Integer userInfoId) {
        Long rankInfo = rakingService.getRankInfo("", RankingType.worldFightingCapacityRaking, userInfoId);
        return rankInfo==null? 0L : rankInfo + 1;
    }
}
